home *** CD-ROM | disk | FTP | other *** search
/ Aminet 30 / Aminet 30 (1999)(Schatztruhe)[!][Apr 1999].iso / Aminet / dev / lang / SmallEiffel.lha / SmallEiffel / lib_show / spread_illness.e < prev   
Text File  |  1998-12-22  |  8KB  |  343 lines

  1. --          This file is part of SmallEiffel The GNU Eiffel Compiler.
  2. --          Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
  3. --            Dominique COLNET and Suzanne COLLIN - colnet@loria.fr 
  4. --                       http://www.loria.fr/SmallEiffel
  5. -- SmallEiffel is  free  software;  you can  redistribute it and/or modify it 
  6. -- under the terms of the GNU General Public License as published by the Free
  7. -- Software  Foundation;  either  version  2, or (at your option)  any  later 
  8. -- version. SmallEiffel is distributed in the hope that it will be useful,but
  9. -- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  10. -- or  FITNESS FOR A PARTICULAR PURPOSE.   See the GNU General Public License 
  11. -- for  more  details.  You  should  have  received a copy of the GNU General 
  12. -- Public  License  along  with  SmallEiffel;  see the file COPYING.  If not,
  13. -- write to the  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  14. -- Boston, MA 02111-1307, USA.
  15. --
  16. --
  17. -- Originally written by Cyril ADRIAN and Antony LE LABOUSSE
  18. --
  19. class SPREAD_ILLNESS
  20.    -- To compile type command : compile SPREAD_ILLNESS make
  21.    --
  22.    -- Also try Optimised version adding options "-boost -O2"
  23.    --
  24. creation {ANY}
  25.    make
  26.    
  27. feature {NONE}
  28.    
  29.    world1, world2: ARRAY2[INTEGER];
  30.    
  31.    empty : INTEGER is 1;
  32.    
  33.    healthy : INTEGER is 0;
  34.    
  35.    di: ARRAY[INTEGER] is
  36.       once
  37.      Result := <<-1,-1,-1,0,1,1,1,0 >>
  38.       end;
  39.    
  40.    dj: ARRAY[INTEGER] is
  41.       once
  42.      Result := <<-1,0,1,1,1,0,-1,-1 >>
  43.       end;
  44.    
  45.    error_msg : STRING is "Error : do it again !%N"
  46.  
  47. feature {ANY}
  48.  
  49.    make is
  50.      -- Try to spreads an illness through a set of people.
  51.       local
  52.      day: INTEGER;
  53.      fed_up: BOOLEAN;
  54.       do
  55.      from  
  56.         day := 1;
  57.         first_day;
  58.      until
  59.         fed_up
  60.      loop
  61.         io.put_string("Day #");
  62.         io.put_integer(day);
  63.         io.put_new_line;
  64.         display;
  65.         io.put_string("Continue ? [y/n] ");
  66.         io.flush;
  67.         io.read_line;
  68.         io.last_string.to_lower;
  69.         fed_up := (io.last_string.first = 'n')
  70.         day := day + 1;
  71.         next_day
  72.      end;
  73.       end;
  74.  
  75. feature {ANY}
  76.    
  77.    first_day is
  78.      -- Create the world in the 1st day's state.
  79.       local
  80.      i, j, ill_state: INTEGER;
  81.      ok: BOOLEAN;
  82.       do
  83.      io.put_string("Default First World (y/n) ? ");
  84.      io.flush;
  85.      io.read_word;
  86.      if io.last_string.is_equal("y") then
  87.         !!world1.from_model(
  88.           <<<<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  89.         <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  90.         <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  91.         <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  92.         <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  93.         <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  94.         <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  95.         <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  96.         <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1>>,
  97.         <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  98.         <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  99.         <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  100.         <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  101.         <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  102.         <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  103.         <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  104.         <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  105.             <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>>>);
  106.      else
  107.         io.put_string("World size : ");
  108.         io.flush;
  109.         io.read_integer;
  110.         !!world1.make(1,io.last_integer,1,io.last_integer);
  111.         io.put_string("%Ne)mpty, i)ll with number of days, h)ealthy%N%N");
  112.         from  
  113.            i := world1.lower1
  114.         until
  115.            i > world1.upper1
  116.         loop
  117.            from  
  118.           j := world1.lower2
  119.            until
  120.           j > world1.upper2
  121.            loop
  122.           from
  123.              ok := false;
  124.           until
  125.              ok
  126.           loop
  127.              io.put_string("State of [");
  128.              io.put_integer(i);
  129.              io.put_character(',');
  130.              io.put_integer(j);
  131.              io.put_string("] : ");
  132.              io.flush;
  133.              io.read_word;
  134.              inspect 
  135.             io.last_string.first
  136.              when 'E','e' then
  137.             if io.last_string.count /= 1 then
  138.                io.put_string(error_msg)
  139.             else
  140.                world1.put(empty,i,j);
  141.                ok := true
  142.             end
  143.              when 'H','h' then
  144.             if io.last_string.count /= 1 then
  145.                io.put_string(error_msg)
  146.             else
  147.                world1.put(healthy,i,j);
  148.                ok := true
  149.             end
  150.              when 'I','i' then
  151.             ok := true;
  152.             io.flush;
  153.             io.read_integer;
  154.             ill_state := io.last_integer;
  155.             ill_state := ill_state.max(1);
  156.             ill_state := ill_state.min(4);
  157.             world1.put(- ill_state,i,j);
  158.              else
  159.             io.put_string(error_msg)
  160.              end;
  161.           end;
  162.           j := j + 1;
  163.            end;
  164.            i := i + 1;
  165.         end;
  166.      end;
  167.      world2 := clone(world1)
  168.       end;
  169.  
  170.    display is
  171.      -- Displays current `world2'.
  172.       local
  173.      i,j : INTEGER;
  174.       do
  175.      io.put_character('+');
  176.      io.put_character('-');
  177.      from  
  178.         i := world1.lower1
  179.      until
  180.         i > world1.upper1
  181.      loop
  182.         io.put_character('-');        
  183.         io.put_character('-');
  184.         i := i+1
  185.      end;
  186.      io.put_character('+');
  187.      io.put_new_line;
  188.      from  
  189.         i := world1.lower1
  190.      until
  191.         i > world1.upper1
  192.      loop
  193.         io.put_character('|');
  194.         io.put_character(' ');
  195.         from  
  196.            j := world1.lower2
  197.         until
  198.            j > world1.upper2
  199.         loop
  200.            inspect 
  201.           world2.item(i,j)
  202.            when empty then
  203.           io.put_character(' ')
  204.            when healthy then
  205.           io.put_character('O')
  206.            else
  207.           io.put_character((- world2.item(i,j)).digit)
  208.            end;
  209.            io.put_character(' ');
  210.            j := j+1
  211.         end;
  212.         io.put_character('|');
  213.         io.put_new_line;
  214.         i := i+1
  215.      end;
  216.      io.put_character('+');
  217.      io.put_character('-');
  218.      from  
  219.         i := world1.lower1
  220.      until
  221.         i > world1.upper1
  222.      loop
  223.         io.put_character('-');
  224.         io.put_character('-');
  225.         i := i+1
  226.      end;
  227.      io.put_character('+');
  228.      io.put_new_line;
  229.       end;
  230.    
  231.    next_day is
  232.      -- `world1' and `world2' are swapped. 
  233.       local
  234.      i,j: INTEGER;
  235.       do
  236.      world1.copy(world2);
  237.      from  
  238.         i := world1.lower1;
  239.      until
  240.         i > world1.upper1
  241.      loop
  242.         from  
  243.            j := world1.lower2;
  244.         until
  245.            j > world1.upper2
  246.         loop
  247.            inspect 
  248.           world1.item(i,j)
  249.            when empty then
  250.            when healthy then
  251.           spread(i,j);
  252.            else
  253.           cure_or_die(i,j);
  254.            end;
  255.            j := j + 1;
  256.         end;
  257.         i := i + 1;
  258.      end;
  259.       end;
  260.    
  261. feature {NONE}
  262.    
  263.    cure_or_die(i,j : INTEGER)  is
  264.      -- When ill, inspects if must be death or more ill or cured.
  265.       do
  266.      inspect      
  267.         - world1.item(i,j)
  268.      when 1 then 
  269.         world2.put(-2,i,j)
  270.      when 2 then 
  271.         die(i,j)
  272.      when 3 then 
  273.         world2.put(-4,i,j)
  274.      when 4 then 
  275.         world2.put(healthy,i,j)
  276.      end
  277.       end;
  278.  
  279.    die(i,j: INTEGER) is
  280.      -- When two days ill, dies or more ill ?
  281.       local
  282.      d,k:INTEGER;
  283.       do
  284.      from  
  285.         d := 1;
  286.      variant
  287.         9 - d
  288.      until
  289.         d > 8
  290.      loop
  291.         if v(i+di.item(d),j+dj.item(d)) <= -2 then
  292.            k := k+1;
  293.         end;
  294.         d := d+1;
  295.      end;
  296.      if k >= 4 then
  297.         world2.put(empty,i,j);
  298.      else
  299.         world2.put(-3,i,j);
  300.      end
  301.       end;
  302.    
  303.    spread(i,j: INTEGER) is
  304.      -- spread the illness ?
  305.       local
  306.      d: INTEGER;
  307.       do
  308.      from  
  309.         d := 1;
  310.      variant
  311.         10 - d
  312.      until
  313.         d = 9
  314.      loop
  315.         if ill(i + di @ d , j + dj @ d) then
  316.            world2.put(-1,i,j);
  317.            d := 9;
  318.         else
  319.            d := d+1;
  320.         end
  321.      end
  322.       end;
  323.    
  324.    ill(i,j: INTEGER): BOOLEAN is
  325.      -- Is there someone is ill at `i', `j'.
  326.       do
  327.      Result := (v(i,j) < 0)
  328.       end;
  329.    
  330.    v(i,j: INTEGER): INTEGER is
  331.      -- Gives `empty' when out of range or the
  332.      -- value in `world1'
  333.       do
  334.      if (world1.lower1 <= i and then i <= world1.upper1)
  335.         and (world1.lower2 <= j and then j <= world1.upper2) then
  336.         Result := world1.item(i,j)
  337.      else
  338.         Result := empty
  339.      end;
  340.       end;
  341.  
  342. end -- SPREAD_ILLNESS
  343.